package com.huashi.common;

import com.huashi.StringUtl.StringUtil;
import com.huashi.emuns.JsonResultEnum;
import com.huashi.exception.CommonToolException;
import com.huashi.func.MethodFunc;
import io.swagger.annotations.ApiModelProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public class CommonUtil {

    private static final Logger log = LoggerFactory.getLogger(CommonUtil.class);

    public static boolean isNotNull(Object obj){
        return isNull(obj) ? false : true;
    }

    public static boolean isNotNull(String... strs){
        boolean ret = true;
        if (isNull(strs))
            return false;

        for (String s : strs){
            if (isNull(s)){
                ret = false;
                break;
            }
        }
        return ret;
    }

    public static boolean isNull (Object obj){
        boolean isNullFlag = true;
        if (obj != null ){
            if (obj instanceof List<?>){
                isNullFlag = isNull((List<?>) obj);
            }else if (obj instanceof Set<?>){
                isNullFlag = isNull((Set<?>) obj);
            }else if (obj instanceof Object[]){
                isNullFlag = isNull((Object[])obj);
            }else if (obj instanceof  Map){
                isNullFlag = isNull((Map)obj );
            }else if (obj instanceof String){
                isNullFlag = isNull((String) obj);
            }else if (obj instanceof  Integer){
                isNullFlag = isNull((Integer) obj);
            }else {
                isNullFlag = false;
            }
        }
        return isNullFlag;
    }

    public static boolean isNull(List<?> list){
        return list == null || list.size() ==0 || list.get(0)==null;
    }

    public static boolean isNull(Set<?> set){
        return set == null || set.size()==0;
    }

    public static boolean isNull(Object[] objects){
        return objects == null || objects.length ==0;
    }

    public static boolean isNull(Map<?, ?> map){
        return map == null || map.isEmpty();
    }

    public static boolean isNull(String str){
        return str == null || "".equals(str.trim()) || "null".equalsIgnoreCase(str.trim());
    }

    public static boolean isNull(Integer integer){
        return integer == null;
    }

    public static void notNull(Object text,String message){
        if (isNull(text)){
            throw new CommonToolException(message);
        }
    }

    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }


    @SuppressWarnings("rawtypes") //消除警告
    public static void checkNotNullField(Object object,String... fields){
        if (CommonUtil.isNull(object)){
            throw new CommonToolException("校验对象为空");
        }
        String result = "";
        try {
            final StringBuilder sb = new StringBuilder();
            for (int i=0;i<fields.length;i++){
                Object value = null;
                if (object instanceof  Map){
                    value = ((Map)object).get(fields[i]);
                }else {
                    final Field field = object.getClass().getDeclaredField(fields[i]);
                    field.setAccessible(true);
                    value = field.get(object);
                }
                addParamStr(sb,fields[i],value);
                CommonUtil.notNull(value,"字段【"+fields[i]+"】不能为空！");
            }
            final String paramStr = sb.toString();
            log.info("传参为 "+ paramStr.substring(0,paramStr.length()-1));
        } catch (CommonToolException ge) {
            result = ge.getMessage();
        }catch (IllegalAccessException ie){
            log.error("校验字段异常,异常原因",ie);
            result = "校验字段异常！";
        }catch (NoSuchFieldException ne){
            log.error("校验字段异常,异常原因",ne);
            result = "未查找到校验字段！";
        }
        if (CommonUtil.isNotNull(result)){
            throw new CommonToolException(JsonResultEnum.ERROR_PARAM_NULL.getCode());
        }
    }

    public static void checkNotNullField(Object object, MethodFunc... methods){
        if (isNull(object)){
            throw new CommonToolException("校验对象为空！");
        }
        if (null != methods && methods.length>0){
            for (MethodFunc method : methods) {
                String methodName = getMethodName(method);
                    try {
                        Object value = object.getClass().getDeclaredMethod(methodName).invoke(object);
                        String fieldName = StringUtil.toLowerCaseFirstOne(methodName.replace("get",""));
                        Field field = object.getClass().getDeclaredField(fieldName);
                        String msg = "";
                        if (field.isAnnotationPresent(ApiModelProperty.class)){
                            ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
                            msg = CommonUtil.isNotNull(apiModelProperty.value()) ? apiModelProperty.value() : fieldName;
                        }
                        CommonUtil.notNull(value,"字段【" + msg + "】不能为空！");
                    } catch (InvocationTargetException e) {
                        throw new CommonToolException("调用异常");
                    } catch (IllegalAccessException e) {
                        throw new CommonToolException("非法访问");
                    } catch (NoSuchMethodException e) {
                        throw new CommonToolException("未找到方法");
                    } catch (NoSuchFieldException e) {
                        throw new CommonToolException("对象属性不存在");
                    }
            }
        }
    }

    private static void addParamStr(StringBuilder sb,String field,Object value){
        sb.append(field);
        sb.append(":");
        sb.append(value);
        sb.append(",");
    }

    public static void checkNotNull(Object... objects){
        for (int i=0;i< objects.length ; i++){
            if (CommonUtil.isNull(objects[i])){
                throw new CommonToolException("必填项不能为空");
            }
        }
    }

    public static <T> String getMethodName(MethodFunc lambda ){
        try{
            Class lambdaClass = lambda.getClass();
            Method method = lambdaClass.getDeclaredMethod("writeReplace");
            method.setAccessible(true);
            SerializedLambda serializableLambda = (SerializedLambda) method.invoke(lambda);
            return serializableLambda.getImplMethodName();
        } catch (ReflectiveOperationException e) {
            throw new CommonToolException("获取MethodFunc方法名异常");
        }
    }
}
